const { pool } = require('../config/database');

class Role {
  // 获取所有角色
  static async findAll(page = 1, limit = 10, search = '') {
    try {
      const offset = (page - 1) * limit;
      let query = 'SELECT * FROM roles';
      
      const params = [];
      if (search) {
        query += ` WHERE name LIKE ? OR code LIKE ? OR description LIKE ?`;
        params.push(`%${search}%`, `%${search}%`, `%${search}%`);
      }
      
      query += ` ORDER BY create_time DESC LIMIT ? OFFSET ?`;
      params.push(limit, offset);
      
      const [rows] = await pool.execute(query, params);
      
      // 获取总数
      let countQuery = 'SELECT COUNT(*) as total FROM roles';
      if (search) {
        countQuery += ` WHERE name LIKE ? OR code LIKE ? OR description LIKE ?`;
      }
      const [countResult] = await pool.execute(countQuery, search ? [`%${search}%`, `%${search}%`, `%${search}%`] : []);
      
      return {
        roles: rows,
        pagination: {
          page: parseInt(page),
          limit: parseInt(limit),
          total: countResult[0].total,
          totalPages: Math.ceil(countResult[0].total / limit)
        }
      };
    } catch (error) {
      throw new Error(`获取角色列表失败: ${error.message}`);
    }
  }

  // 根据ID获取角色
  static async findById(id) {
    try {
      const [rows] = await pool.execute('SELECT * FROM roles WHERE id = ?', [id]);
      return rows[0] || null;
    } catch (error) {
      throw new Error(`获取角色失败: ${error.message}`);
    }
  }

  // 根据代码获取角色
  static async findByCode(code) {
    try {
      const [rows] = await pool.execute('SELECT * FROM roles WHERE code = ?', [code]);
      return rows[0] || null;
    } catch (error) {
      throw new Error(`根据代码获取角色失败: ${error.message}`);
    }
  }

  // 获取所有角色（不分页，用于下拉选择）
  static async getAllRoles() {
    try {
      const [rows] = await pool.execute('SELECT id, name, code FROM roles ORDER BY name');
      return rows;
    } catch (error) {
      throw new Error(`获取所有角色失败: ${error.message}`);
    }
  }

  // 创建角色
  static async create(roleData) {
    try {
      const { name, code, description } = roleData;
      
      // 检查角色代码是否已存在
      const existingRole = await this.findByCode(code);
      if (existingRole) {
        throw new Error('角色代码已存在');
      }
      
      const [result] = await pool.execute(`
        INSERT INTO roles (name, code, description)
        VALUES (?, ?, ?)
      `, [name, code, description]);
      
      return { id: result.insertId, ...roleData };
    } catch (error) {
      throw new Error(`创建角色失败: ${error.message}`);
    }
  }

  // 更新角色
  static async update(id, roleData) {
    try {
      const { name, code, description } = roleData;
      
      // 检查角色是否存在
      const existingRole = await this.findById(id);
      if (!existingRole) {
        throw new Error('角色不存在');
      }
      
      // 如果更新角色代码，检查是否与其他角色冲突
      if (code && code !== existingRole.code) {
        const roleWithSameCode = await this.findByCode(code);
        if (roleWithSameCode) {
          throw new Error('角色代码已存在');
        }
      }
      
      const [result] = await pool.execute(`
        UPDATE roles 
        SET name = ?, code = ?, description = ?
        WHERE id = ?
      `, [name, code, description, id]);
      
      if (result.affectedRows === 0) {
        throw new Error('更新失败，角色可能不存在');
      }
      
      return await this.findById(id);
    } catch (error) {
      throw new Error(`更新角色失败: ${error.message}`);
    }
  }

  // 删除角色
  static async delete(id) {
    try {
      // 检查是否有用户使用此角色
      const [users] = await pool.execute('SELECT COUNT(*) as count FROM users WHERE role_id = ?', [id]);
      if (users[0].count > 0) {
        throw new Error('无法删除角色，有用户正在使用此角色');
      }
      
      const [result] = await pool.execute('DELETE FROM roles WHERE id = ?', [id]);
      
      if (result.affectedRows === 0) {
        throw new Error('删除失败，角色可能不存在');
      }
      
      return true;
    } catch (error) {
      throw new Error(`删除角色失败: ${error.message}`);
    }
  }

  // 批量删除角色
  static async deleteMultiple(ids) {
    try {
      // 检查是否有用户使用这些角色
      const placeholders = ids.map(() => '?').join(',');
      const [users] = await pool.execute(`SELECT COUNT(*) as count FROM users WHERE role_id IN (${placeholders})`, ids);
      if (users[0].count > 0) {
        throw new Error('无法删除角色，有用户正在使用这些角色');
      }
      
      const [result] = await pool.execute(`DELETE FROM roles WHERE id IN (${placeholders})`, ids);
      
      return result.affectedRows;
    } catch (error) {
      throw new Error(`批量删除角色失败: ${error.message}`);
    }
  }

  // 获取角色权限
  static async getPermissions(roleId) {
    try {
      const [rows] = await pool.execute(`
        SELECT permission FROM role_permissions WHERE role_id = ?
      `, [roleId]);
      
      return rows.map(row => row.permission);
    } catch (error) {
      throw new Error(`获取角色权限失败: ${error.message}`);
    }
  }

  // 设置角色权限
  static async setPermissions(roleId, permissions) {
    try {
      // 先删除现有权限
      await pool.execute('DELETE FROM role_permissions WHERE role_id = ?', [roleId]);
      
      // 插入新权限
      if (permissions && permissions.length > 0) {
        const values = permissions.map(permission => [roleId, permission]);
        const placeholders = values.map(() => '(?, ?)').join(',');
        await pool.execute(`
          INSERT INTO role_permissions (role_id, permission) VALUES ${placeholders}
        `, values.flat());
      }
      
      return true;
    } catch (error) {
      throw new Error(`设置角色权限失败: ${error.message}`);
    }
  }

  // 获取角色统计信息
  static async getStats() {
    try {
      const [totalRoles] = await pool.execute('SELECT COUNT(*) as total FROM roles');
      const [rolesWithUsers] = await pool.execute(`
        SELECT COUNT(DISTINCT r.id) as with_users 
        FROM roles r 
        INNER JOIN users u ON r.id = u.role_id
      `);
      
      return {
        total: totalRoles[0].total,
        withUsers: rolesWithUsers[0].with_users
      };
    } catch (error) {
      throw new Error(`获取角色统计失败: ${error.message}`);
    }
  }

  // 获取角色已分配菜单ID
  static async getMenus(roleId) {
    try {
      const [rows] = await pool.execute('SELECT menu_id FROM role_menus WHERE role_id = ?', [roleId]);
      return rows.map(r => r.menu_id);
    } catch (error) {
      throw new Error(`获取角色菜单失败: ${error.message}`);
    }
  }

  // 分配菜单权限
  static async setMenus(roleId, menuIds) {
    const conn = await pool.getConnection();
    try {
      await conn.beginTransaction();
      await conn.execute('DELETE FROM role_menus WHERE role_id = ?', [roleId]);
      if (menuIds && menuIds.length > 0) {
        const values = menuIds.map(id => [roleId, id]);
        await conn.query('INSERT INTO role_menus (role_id, menu_id) VALUES ?', [values]);
      }
      await conn.commit();
      return true;
    } catch (error) {
      await conn.rollback();
      throw new Error(`分配菜单权限失败: ${error.message}`);
    } finally {
      conn.release();
    }
  }
}

module.exports = Role; 